package com.weapp.system.controller.api;

import cn.hutool.core.util.URLUtil;
import cn.hutool.json.JSONUtil;
import io.minio.*;
import io.minio.messages.Item;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @author jsy
 * @description: minio 对外Api
 * @date 2022/7/12 11:26
 */
@RestController
@Slf4j
public class MinioController {

  @Autowired
  private MinioClient minioClient;

  @Value("${minio.bucketName}")
  private String bucketName;

  @GetMapping("/list")
  @ApiOperation(value = "文件列表查询", tags = "文件查询")
  public List<Object> list() throws Exception {
    Iterable<Result<Item>> results = minioClient.listObjects(
      ListObjectsArgs.builder().bucket(bucketName).recursive(true).build());
    Iterator<Result<Item>> iterator = results.iterator();
    List<Object> itemList = new ArrayList<>();
    String format = "{'fileName':'%s','fileSize':'%s'}";
    while (iterator.hasNext()) {
      Item item = iterator.next().get();
      itemList.add(JSONUtil.parse(String.format(format, item.objectName(), item.size())));
    }
    return itemList;
  }

  @DeleteMapping("/delete/{fileName}")
  @ApiOperation(value = "文件删除", tags = "文件删除")
  public String delete(@PathVariable("fileName") String fileName) {
    try {
      minioClient.removeObject(
        RemoveObjectArgs.builder().bucket(bucketName).object(fileName).build());
    } catch (Exception e) {
      log.error("文件删除失败：{}", e.getMessage());
      return "删除失败";
    }
    return "删除成功";
  }

  @PostMapping("/upload")
  @ApiOperation(value = "文件批量上传", tags = "文件上传")
  public String upload(@RequestParam(value = "file", required = false) MultipartFile[] file) {
    if (file == null || file.length == 0) {
      return "上传文件不能为空";
    }
    List<String> originalList = new ArrayList<>(file.length);
    for (MultipartFile multipartFile : file) {
      String filename = multipartFile.getOriginalFilename();
      originalList.add(filename);
      try {
        InputStream in = multipartFile.getInputStream();
        minioClient.putObject(
          PutObjectArgs.builder().bucket(bucketName).object(filename).stream(
            in, multipartFile.getSize(), -1)
            .contentType(multipartFile.getContentType())
            .build());
        in.close();
      } catch (Exception e) {
        log.error("上传文件失败：{}", e.getMessage());
        return "上传文件失败";
      }
    }
    return "上传文件成功";
  }

  @GetMapping("/download/{fileName}")
  @ApiOperation(value = "文件下载", tags = "文件下载")
  public void download(HttpServletResponse response, @PathVariable("fileName") String fileName) throws Exception {
    InputStream in = null;
    try {
      //获取对象值
      StatObjectResponse statObjectResponse = minioClient.statObject(
        StatObjectArgs.builder().bucket(bucketName).object(fileName).build());
      response.setContentType(statObjectResponse.contentType());
      response.setHeader("Content-Disposition", "attachment;fileName=" + URLUtil.encode(fileName));
      //下载文件
      in = minioClient.getObject(
        GetObjectArgs.builder()
          .bucket(bucketName)
          .object(fileName)
          .build());
      IOUtils.copy(in, response.getOutputStream());
    } catch (Exception e) {
      log.error("文件下载失败：{}", e.getMessage());
    } finally {
      if (in != null) {
        try {
          in.close();
        } catch (IOException e) {
          log.error(e.getMessage());
        }
      }
    }
  }
}
